/* The ever menecing protector of the jewels. */
/* A bitmap is used to quickly draw and erase */
/* the guard.  This requires MS-Windows calls */
/* but is faster than using a polygon.        */!!

inherit(Object, #Guard, #(bitmap /* guard's graphic def'n */
dir    /* direction of movement */
pen    /* Object to draw/erase  */
speed  /* how quick he goes!    */
x      /* x position            */
y      /* y position            */), 2, nil)!!

now(GuardClass)!!

/* Create and initialize a new guard. */
/**************************************/
Def  new(self | guard, dirArray)
{ guard := new(self:Behavior);  /* Get something to work with. */
  guard.x := random(222) + 5;   /* Get an initial position. */
  guard.y := random(186) + 5;
  guard.speed := random(4) + 4; /* Find out how fast we are */
  guard.dir := new(Array, 2);   /* Find out which way we're going */
  dirArray := #("N", "S", "W", "E");
  guard.dir[0] := dirArray[random(1)];
  guard.dir[1] := dirArray[random(1)+2];
                                /* Find out what we look like */
  guard.bitmap := Call LoadBitmap(HInstance, asciiz("funman"));
  setGraphics(guard);           /* Find out how to draw/erase ourself */
  ^guard
}!!

now(Guard)!!

/* Return size in pixels. */
/**************************/
Def  size(self)
{ ^10
}!!

/* Set up the devices to draw & erase. */
/***************************************/
Def  setGraphics(self)
{ pen := Call GetStockObject(BLACK_BRUSH);
}!!

/* Return the mov't factor. */
/****************************/
Def  speed(self)
{ ^speed
}!!

/* Change to the specified direction. */
/**************************************/
Def  setDir(self, newDir)
{  select
    case newDir = "N" cor newDir = "S"
    is dir[0] := newDir;
    endCase
    case newDir = "W" cor newDir = "E"
    is dir[1] := newDir;
    endCase
  endSelect;
}!!

/* Return the guard's y position */
/*********************************/
Def  y(self)
{ ^y
}!!

/* Return the guard's x position */
/*********************************/
Def  x(self)
{ ^x
}!!

/* Display the guard.           */
/* Lots of MS-Windows but fast. */
/********************************/
Def  draw(self, hDC | hMemDC)
{ Call SelectObject(hDC, pen);             /* Get pen for the window.  */
  hMemDC := Call CreateCompatibleDC(hDC);  /* Create a compatable hDC. */
  Call SelectObject(hMemDC, bitmap);       /* Get bitmap image.        */
  Call SelectObject(hMemDC, pen);          /* Get pen for the bitmap.  */
  Call BitBlt(hDC, x-10, y-10, 20, 20,     /* Draw (or erase) bitmap   */
      hMemDC, 0, 0, 0x004916C5);           /*   by inverting pixels.   */
  Call DeleteDC(hMemDC);                   /* Clean up.                */

}!!

/* Move the guard based on */
/* dir and speed.          */
/***************************/
Def  move(self, hDC)
{ draw(self, hDC);     /* Erase the guard. */
  select               /* Set new position. */
    case dir[0] = "N"
    is y := y - speed;
    endCase
    case dir[0] = "S"
    is y := y + speed;
    endCase
  endSelect;
  select
    case dir[1] = "W"
    is x := x - speed;
    endCase
    case dir[1] = "E"
    is x := x + speed;
    endCase
  endSelect;
  draw(self, hDC);    /* Draw the guard. */
}!!

